﻿using System.Linq;
using System.Xml;
using DataScripter.Scripting;
using DataScripter.Scripting.InputSources;
using DataScripter.Scripting.Output;
using DataScripter.Scripting.OutputDestinations;
using DataScripter.Scripting.ProcessDefinitions;
using DataScripter.Scripting.Processes;
using DataScripter.Scripting.Processes.Morphs;
using DataScripter.Scripting.ScriptDefinitions;
using DataScripter.XmlInterpreter.XmlInterpreters;

namespace DataScripter.XmlInterpreter
{
// ReSharper disable UnusedMember.Global
    public class XmlEngineConfiguratorv4 : IXmlEngineConfigurator
// ReSharper restore UnusedMember.Global
    {
        public IEngine Configure(IEngine engine, XmlDocument document, ScriptOptions scriptOptions)
        {
            XmlElement script = document.DocumentElement;
            if (script == null)
            {
                return engine;
            }

            scriptOptions.ScriptOutputType = ScriptOutputType.File;

            foreach (XmlElement element in script.ChildNodes.OfType<XmlElement>())
            {
                switch (element.Name)
                {
                    case "Types":
                        new TypesInterpreter(engine).InterpretElement(element);
                        break;
                    case "ProcessTypes":
                        new ProcessTypesInterpreter(engine).InterpretElement(element);
                        break;
                    case "FieldMorphs":
                        new FieldMorphsInterpreter(engine).InterpretElement(element);
                        break;
                    case "Import":
                        ImportDocument(element, engine, scriptOptions);
                        break;
                    case "InputSource":
                        IInputSource source = new InputSourceInterpreter(engine).InterpretElement(element);
                        engine.RegisterType(source.Name, source);
                        break;
                    case "Output":
                        IOutputDestination destination = new OutputDestinationInterpreter(engine).InterpretElement(element);
                        engine.RegisterType(destination.Name, destination);
                        break;
                    case "ScriptDefinition":
                        IScriptDefinition scriptDefinition = new ScriptDefinitionInterpreter(engine).InterpretElement(element);
                        engine.RegisterType(scriptDefinition.Name, scriptDefinition);
                        break;
                    case "Processes":
                        IProcessDefinition processDefinition = new ProcessDefinitionInterpreter(engine).InterpretElement(element);
                        engine.RegisterType(processDefinition.Name, processDefinition);
                        break;
                    case "MorphActions":
                        IMorphActionsDefinition morphActionsDefinition = new MorphActionsDefinitionInterpreter(engine).InterpretElement(element);
                        engine.RegisterType(morphActionsDefinition.Name, morphActionsDefinition);
                        break;
					case "TableList":
						ITableList tableList = new TableListInterpreter(engine).InterpretElement(element);
						engine.RegisterType(tableList.Name, tableList);
						break;
				}
            }

            IFileOutputDestination fileOutputDestination = ((IFileOutputDestination)engine.Resolve<IOutputDestination>());
            if (fileOutputDestination != null)
            {
                scriptOptions.Filename = fileOutputDestination.OutputPath;
            }

            return engine;
        }

        private void ImportDocument(XmlElement element, IEngine engine, ScriptOptions scriptOptions)
        {
            string path = element.GetAttribute("Path");
            XmlDocument doc = new XmlDocument();
            doc.Load(path);
            Configure(engine, doc, scriptOptions);
        }
    }
}